﻿using CommunityToolkit.Mvvm.ComponentModel;
using Company.Hardware.Hikvision;
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace Company.Hardware
{
    public class Camera : ObservableObject,ICamera
    {
        private bool _initialized;
        private bool _connected;
        private string _message;
        private string _value;
        private string _hex;
        private IntPtr intPtr;
        private CHCNetSDK.MSGCallBack_V31 callBack = null;
        private int userId;


        public bool Initialized { get => _initialized; set => SetProperty(ref _initialized, value); }
        public bool Connected { get => _connected; set => SetProperty(ref _connected, value); }
        public string Message { get => _message; set => SetProperty(ref _message, value); }
        public string Value { get => _value; set => SetProperty(ref _value, value); }

       

        public event Action<string> MessageChanged;
        public event Action<string> ValueChanged;

        public bool Close()
        {
            return CHCNetSDK.NET_DVR_Cleanup();
        }

        public bool Init(string ip, int port, string user, string password, IntPtr intPtr)
        {
            this.intPtr = intPtr;
            try
            {
                bool init = CHCNetSDK.NET_DVR_Init();
                if (!init)
                {
                    MessageChanged?.Invoke("初始化海康SDK失败");
                    return false;
                }

                // 开启日志
                CHCNetSDK.NET_DVR_SetLogToFile(3, @"c:\log\", true);
                //设置透传报警类型
                CHCNetSDK.NET_DVR_LOCAL_GENERAL_CFG cfg = new CHCNetSDK.NET_DVR_LOCAL_GENERAL_CFG();
                cfg.byAlarmJsonPictureSeparate = 1;
                int size = Marshal.SizeOf(cfg);
                IntPtr ptr = Marshal.AllocHGlobal(size);
                if(!CHCNetSDK.NET_DVR_SetSDKLocalCfg(17, ptr))
                {
                    var error = CHCNetSDK.NET_DVR_GetLastError();
                    MessageChanged?.Invoke($"设置SDK初始化参数失败，error={error}");
                    return false;
                }
                Marshal.FreeHGlobal(ptr);

                //设置报警回调函数
                if(callBack == null)
                {
                    callBack = new CHCNetSDK.MSGCallBack_V31(MSGCallback);
                }
                CHCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(callBack, IntPtr.Zero);

                // 登录摄像头
                CHCNetSDK.NET_DVR_DEVICEINFO_V30 DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V30();
                userId = CHCNetSDK.NET_DVR_Login_V30(ip, port, user, password, ref DeviceInfo);
                if(userId < 0)
                {
                    var error = CHCNetSDK.NET_DVR_GetLastError();
                    MessageChanged?.Invoke($"摄像头登录失败，error={error}");
                    return false;
                }

                MessageChanged?.Invoke($"摄像头登录成功");
                Initialized = true;
                Connected = true;
                return true;
            }
            catch (Exception ex)
            {
                MessageChanged?.Invoke(ex.Message);
                return false;
            }
        }

        // 在这里获取识别的车牌号
        private bool MSGCallback(int lCommand, ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
        {
            if(lCommand == CHCNetSDK.COMM_ITS_PLATE_RESULT)
            {
                CHCNetSDK.NET_ITS_PLATE_RESULT result = new CHCNetSDK.NET_ITS_PLATE_RESULT();
                result = (CHCNetSDK.NET_ITS_PLATE_RESULT)Marshal.PtrToStructure(pAlarmInfo, typeof(CHCNetSDK.NET_ITS_PLATE_RESULT));
                // 得到车牌号
                Value = System.Text.Encoding.GetEncoding("GBK").GetString(result.struPlateInfo.sLicense).TrimEnd('\0');
                // 触发事件
                ValueChanged?.Invoke(Value);
            }
            return true;
        }

        public bool Open()
        {
            try
            {
                if (Initialized)
                {
                    //开启布防
                    CHCNetSDK.NET_DVR_SETUPALARM_PARAM parm = new CHCNetSDK.NET_DVR_SETUPALARM_PARAM();
                    parm.dwSize = (uint)Marshal.SizeOf(parm);
                    parm.byLevel = 1;
                    parm.byAlarmInfoType = 1;
                    parm.byFaceAlarmDetection = 1;
                    var handle = CHCNetSDK.NET_DVR_SetupAlarmChan_V41(userId, ref parm);
                    if (handle < 0)
                    {
                        var error = CHCNetSDK.NET_DVR_GetLastError();
                        MessageChanged?.Invoke($"摄像头打开失败, error={error}");
                        return false;
                    }

                    // 开启预览
                    CHCNetSDK.NET_DVR_PREVIEWINFO preview = new CHCNetSDK.NET_DVR_PREVIEWINFO();
                    preview.hPlayWnd = intPtr; // 预览窗口
                    preview.lChannel = 1;
                    preview.dwStreamType = 0;
                    preview.dwLinkMode = 0;  // TCP连接方式 
                    preview.bBlocked = true; //  阻塞取流
                    preview.dwDisplayBufNum = 1; // 播放最大缓冲帧数
                    preview.byProtoType = 0;
                    preview.byPreviewMode = 0;
                    IntPtr puser = IntPtr.Zero;

                    // 打开预览
                    var previewHandle = CHCNetSDK.NET_DVR_RealPlay_V40(userId, ref preview, null, puser);
                    if(previewHandle < 0)
                    {
                        var error = CHCNetSDK.NET_DVR_GetLastError();
                        MessageChanged?.Invoke($"摄像头预览失败,error={error}");
                        return false;
                    }
                    return true;
                }
                else
                {
                    MessageChanged?.Invoke($"请先初始化摄像头SDK");
                    return true;
                }
            }
            catch (Exception ex)
            {
                MessageChanged?.Invoke(ex.Message);
                return false;
            }
        }

        public void Trigger(string carName)
        {
            Value = carName;
            if (string.IsNullOrEmpty(Value))
            {
                Value = $"渝A{new Random().Next(111,999)}F";
            }
            ValueChanged?.Invoke(Value);
        }
    }
}
